var bum = bum || {};
bum.isNull = function(val) {
	return val === null || val === undefined;
}
bum.isDebug = false;
bum.pixelRatio = window.devicePixelRatio || 1;

/* LISTENER */
bum.listener = {
	_listenters : {},

	add : function(evt, action) {
		if (bum.isNull(bum.listener._listenters[evt])) {
			bum.listener._listenters[evt] = [];
		}
		bum.listener._listenters[evt].push(action);
	},

	fire : function(evt, data) {
		if (bum.isNull(bum.listener._listenters[evt])) {
			return;
		}
		for (var len = bum.listener._listenters[evt].length, i = 0; i < len; i++) {
			bum.listener._listenters[evt][i](data);
		}
	}
};

/* BOOTSTRAP AJAX TAB */
$(document).ready(function() {
	$(document).on('click touch', '.nav-tabs [data-toggle="tabajax"]', function() {
		var T = $(this);
		$(T.attr('href')).load(T.attr('ajax-href'), {
			ajax : 1
		});
		T.tab('show');

		// clear
		// T = null;
		return false;
	});

	$(window).unload(function() {
		$('#pageLoading').show();
	});
});

/* =============== END UTILS */

// =================================================
/**
 * COMMON LIB
 */
String.prototype.startsWith = function(str) {
	return (this.match("^" + str) == str)
};
String.prototype.endsWith = function(str) {
	return (this.match(str + "$") == str)
};
String.prototype.hashCode = function() {
	var hash = 0, i, ch;
	if (this.length == 0)
		return hash;
	for (i = 0, l = this.length; i < l; i++) {
		ch = this.charCodeAt(i);
		hash = ((hash << 5) - hash) + ch;
		hash |= 0; // Convert to 32bit integer
	}
	return hash;
};

/* APP EVENTS */
var WEBAPP = {
	load : function() {
		$('#pageLoading').fadeOut();
		var id = $('main [role=page]').attr('id');
		if (WEBAPP[id] != undefined && typeof WEBAPP[id] === "function") {
			WEBAPP[id]();
		}
	},

	unload : function() {
		$('#pageLoading').fadeIn();
		id = $('main [role=page]').attr('id');
		if (id) {
			id = id + 'Unload';
		}
		if (WEBAPP[id] != undefined && typeof WEBAPP[id] === "function") {
			WEBAPP[id]();
		}
	}
};

$(function() {
	WEBAPP.load();
});

WEBAPP['homeRedirect'] = function() {
	location.href = "/app/home/bum";
};

bum.util = {
	formatNumber : function(num) {
		return num.toString().replace(/(\d)(?=(\d{3})+(?!\d))/g, "$1,");
	},

	parse : function(data, startToken, endToken) {
		var startIdx = 0;
		if (startToken != null) {
			startIdx = data.indexOf(startToken);
			if (startIdx < 0) {
				return null;
			}
			startIdx += startToken.length;
		}

		var endIdx = 0;
		if (endToken != null) {
			endIdx = data.indexOf(endToken, startIdx);
		} else {
			endIdx = data.length;
		}
		if (endIdx < 0) {
			return null;
		}

		return data.substring(startIdx, endIdx);
	},

	BASE64_CHARS : 'HefghABCVWXYZabcdFGijDEIJKLMNOPQRpqrstuvwxyz0123456789-.STUklmno',
	base64 : function(bytes) {
		var chars = [];
		var charsLen = 0;

		var mask = 0x3F;

		var i = 0;
		var size = bytes.length;
		while (i < size) {
			var b0 = bytes[i++];
			var b1 = (i < size) ? bytes[i++] : 0;
			var b2 = (i < size) ? bytes[i++] : 0;

			chars[charsLen++] = this.BASE64_CHARS[(b0 >> 2) & mask];
			chars[charsLen++] = this.BASE64_CHARS[((b0 << 4) | ((b1 & 0xFF) >> 4)) & mask];
			chars[charsLen++] = this.BASE64_CHARS[((b1 << 2) | ((b2 & 0xFF) >> 6)) & mask];
			chars[charsLen++] = this.BASE64_CHARS[b2 & mask];
		}

		switch (size % 3) {
		case 1:
			chars[--charsLen] = '_';
		case 2:
			chars[--charsLen] = '_';
		}

		return chars.join("");
	},
};

$.fn.scrollTo = function(target, options, callback) {
	if (typeof options == 'function' && arguments.length == 2) {
		callback = options;
		options = target;
	}
	var settings = $.extend({
		scrollTarget : target,
		offsetTop : 50
	}, options);
	return this.each(function() {
		var scrollPane = $(this);
		var scrollTarget = (typeof settings.scrollTarget == "number") ? settings.scrollTarget : $(settings.scrollTarget);
		var scrollY = (typeof scrollTarget == "number") ? scrollTarget : scrollTarget.offset().top + scrollPane.scrollTop() - parseInt(settings.offsetTop);
		scrollPane.scrollTop(scrollY, function() {
			if (typeof callback == 'function') {
				callback.call(this);
			}
		});
	});
};